package xc.src.线程同步安全问题;

public class SellTicket implements Runnable {
    //定义100张票
//    private int tickets = 100;

    private static int tickets = 100;
    private Object object = new Object();//在方法外定义了Object类进行上锁
    private int x = 0;

    @Override
    public void run() {
        //出现了负数票的情况
        while (true) {
            if (x % 2 == 0) {
                //Tickets =100;
                //t1,t2,t3
                //假设t1抢到了CPU的执行权
                //假设t2在t1休息时抢到了CPU的执行权，但是过程被锁上了
//                synchronized (object) {//同步代码块将多条语句操作共享数据代码锁起来了

//                synchronized (this) {
                  synchronized (SellTicket.class) {//得到了该类的字节码文件对象
                    //t1进来后，就会将这段代码锁起来
                    if (tickets > 0) {
                        //通过sleep方法来模拟出票时间
                        try {
                            Thread.sleep(100);
                            //t1休息100毫秒
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                        //窗口1正在出售第100张票
                        System.out.println(Thread.currentThread().getName() + "正在售出第" + tickets + "张票");
                        tickets--;//Tickets= 99;
                    }
                }
                //Tickets通过锁出来了，出来了之后锁就被释放了，之后在抢进去在锁！！！
            } else {
//                synchronized (object) {//同步代码块将多条语句操作共享数据代码锁起来了同一把锁
//                    //t1进来后，就会将这段代码锁起来
//                    if (tickets > 0) {
//                        //通过sleep方法来模拟出票时间
//                        try {
//                            Thread.sleep(100);
//                            //t1休息100毫秒
//                        } catch (InterruptedException e) {
//                            throw new RuntimeException(e);
//                        }
//                        //窗口1正在出售第100张票
//                        System.out.println(Thread.currentThread().getName() + "正在售出第" + tickets + "张票");
//                        tickets--;//Tickets= 99;
//                    }
//                }

                //写一个方法进行卖票
                sellTicket();
            }
            x++;
        }
    }

//    private void sellTicket() {
//        synchronized (object) {//同步代码块将多条语句操作共享数据代码锁起来了同一把锁
//            //t1进来后，就会将这段代码锁起来
//            if (tickets > 0) {
//                //通过sleep方法来模拟出票时间
//                try {
//                    Thread.sleep(100);
//                    //t1休息100毫秒
//                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                }
//                //窗口1正在出售第100张票
//                System.out.println(Thread.currentThread().getName() + "正在售出第" + tickets + "张票");
//                tickets--;//Tickets= 99;
//            }
//        }
//    }


    //同步方法;将synchronized加到方法上
    //格式： 修饰符 synchronized 返回值类型 方法名（方法参数）{ }
//    private synchronized void sellTicket() {//加上同步锁了，是第二个锁的对象是this
//        //t1进来后，就会将这段代码锁起来
//        if (tickets > 0) {
//            //通过sleep方法来模拟出票时间
//            try {
//                Thread.sleep(100);
//                //t1休息100毫秒
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
//            //窗口1正在出售第100张票
//            System.out.println(Thread.currentThread().getName() + "正在售出第" + tickets + "张票");
//            tickets--;//Tickets= 99;
//        }
//    }

    //同步静态方法
    // 格式：
    //修饰符 static synchronized 返回值类型 方法名（方法参数）{ }
    private static synchronized void sellTicket() {//同步静态方法锁对象是类名.class
        //t1进来后，就会将这段代码锁起来
        if (tickets > 0) {
            //通过sleep方法来模拟出票时间
            try {
                Thread.sleep(100);
                //t1休息100毫秒
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            //窗口1正在出售第100张票
            System.out.println(Thread.currentThread().getName() + "正在售出第" + tickets + "张票");
            tickets--;//Tickets= 99;
        }
    }
}